Senate Intelligence
Subcommittee Hearing,
1975
h) getc or fgetc. i) fgets. j) fopen. k) fread. l) fseek.
file pointer.
b)
c)
/* Exercise 23.5 Solution *//* NOTE: This program was run using the */
/* data in Exercise 23.8 */
#include <stdio.h>
#include <stdlib.h>
main()
{
int masterAccount, transactionAccount;
float masterBalance, transactionBalance;
char masterName[23];
FILE *ofPtr, *tfPtr, *nfPtr;
if ((ofPtr = fopen("oldmast.dat", "r")) == NULL) {
printf("Unable to open oldmast.dat\n");
exit(1);
}
if ((tfPtr = fopen("trans.dat", "r")) == NULL) {
printf("Unable to open trans.dat\n");
exit(1);
}
if ((nfPtr = fopen("newmast.dat", "w")) == NULL) {
printf("Unable to open newmast.dat\n");
exit(1);}
printf("Processing....\n");
fscanf(tfPtr, "%d%f", &transactionAccount, &transactionBalance);
while (!feof(tfPtr)) {
fscanf(ofPtr, "%d%s%f", &masterAccount, masterName, &masterBalance);
while (masterAccount < transactionAccount && !feof(ofPtr)) {
fprintf(nfPtr, "%d %s %.2f\n", masterAccount, masterName,
masterBalance); printf("%d %s %.2f\n", masterAccount, masterName, masterBalance);
fscanf(ofPtr, "%d%s%f", &masterAccount, masterName,
&masterBalance); }
if (masterAccount == transactionAccount) {
masterBalance += transactionBalance;
fprintf(nfPtr, "%d %s %.2f\n", masterAccount, masterName,
masterBalance); printf("%d %s %.2f\n", masterAccount, masterName, masterBalance);
}
else if (masterAccount > transactionAccount) {
printf("Unmatched transaction record for account %d\n",
transactionAccount);
fprintf(nfPtr, "%d %s %.2f\n", masterAccount, masterName,
masterBalance);
printf("%d %s %.2f\n", masterAccount, masterName, masterBalance);}
else
printf("Unmatched transaction record for account %d\n",
transactionAccount);
fscanf(tfPtr, "%d%f", &transactionAccount, &transactionBalance);
}
while (!feof(ofPtr)) {
fscanf(ofPtr, "%d%s%f", &masterAccount, masterName, &masterBalance);
fprintf(nfPtr, "%d %s %.2f", masterAccount, masterName,
masterBalance); printf("%d %s %.2f", masterAccount, masterName, masterBalance);
}
fclose(ofPtr);
fclose(tfPtr);
fclose(nfPtr);
return 0;
}
Processing....
100 Jones 375.31
300 Smith 89.30
Unmatched transaction record for account 400
500 Sharp 0.00
700 Green -14.22
Unmatched transaction record for account 900
/* Exercise 23.6 Solution */#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
void initializeFile(FILE *);
void inputData(FILE *);
int instructions(void);
void listTools(FILE *);
void updateRecord(FILE *);
void insertRecord(FILE *);
void deleteRecord(FILE *);
struct hardwareData {
int partNumber;
char toolName[30];
int inStock;
float unitPrice;
};
main()
{
FILE *filePtr;
char response[2];
int process;
printf("Should the file be initialized (Y or N): ");
scanf("%s", response);
while (toupper(response[0]) != 'Y' && toupper(response[0]) != 'N') {
printf("Invalid response. Enter Y or N: ");
scanf("%s", response);
}
if (toupper(response[0]) == 'Y') {
if ((filePtr = fopen("hardware.dat", "w")) == NULL) {
printf("File could not be opened.\n");exit(1);
}
initializeFile(filePtr);
inputData(filePtr);
fclose(filePtr);
}
if ((filePtr = fopen("hardware.dat", "r+")) == NULL) {
printf("File could not be opened.\n");
exit(1);
}while ((process = instructions()) != 5) {
switch (process) {
case 1:
listTools(filePtr);
break;
case 2:
updateRecord(filePtr);
break;
case 3:
insertRecord(filePtr);
break;
case 4:deleteRecord(filePtr);
break;
}
}
fclose(filePtr);
return 0;
}
void initializeFile(FILE *fPtr)
{
struct hardwareData blankItem = {0, "", 0, 0.0};int i;
for (i = 0; i <= 99; i++)
fwrite(&blankItem, sizeof(struct hardwareData), 1, fPtr);
}
void inputData(FILE *fPtr)
{
struct hardwareData temp;
char c;
printf("Enter the partnumber (0 - 99, -1 to end input): ");
scanf("%d", &temp.partNumber);
while (temp.partNumber != -1) {
printf("Enter the tool name, quantity, and price:\n");
scanf(" %[^0-9] %d%f", temp.toolName, &temp.inStock,
&temp.unitPrice); fseek(fPtr, temp.partNumber * sizeof(struct hardwareData),
SEEK_SET);
fwrite(&temp, sizeof(struct hardwareData), 1, fPtr);
printf("Enter the partnumber (0 - 99, -1 to end input): ");
scanf("%d", &temp.partNumber);
}
}
int instructions(void)
{
int choice;
printf("\n%s\n%s\n%s\n%s\n%s\n%s\n? ", "Enter a choice:",
"1 List all tools.", "2 Update record.", "3 Insert record.",
"4 Delete record.", "5 End program.");scanf("%d", &choice);
while (choice < 1 || choice > 5) {
printf("Invalid choice. Enter again: ");
scanf("%d", &choice);
}
return choice;
}
void listTools(FILE *fPtr)
{struct hardwareData temp;
fseek(fPtr, sizeof(struct hardwareData), SEEK_SET);
printf("%8s %-29s%10s%8s\n", "Record #", "Tool name", "Quantity",
"Cost");
while (!feof(fPtr)) {
fread(&temp, sizeof(struct hardwareData), 1, fPtr);
if (temp.partNumber)
printf("%-8d %-29s%10d%8.2f\n", temp.partNumber,
temp.toolName, temp.inStock, temp.unitPrice);
}}
void updateRecord(FILE *fPtr)
{
struct hardwareData temp;
int part;
printf("Enter the partnumber for update: ");
scanf("%d", &part);
fseek(fPtr, part * sizeof(struct hardwareData), SEEK_SET);fread(&temp, sizeof(struct hardwareData), 1, fPtr);
if (temp.partNumber) {
printf("%8s %-29s%10s%8s\n", "Record #", "Tool name", "Quantity","Cost");
printf("%-8d %-29s%10d%8.2f\n", temp.partNumber, temp.toolName,
temp.inStock, temp.unitPrice);
printf("Enter the tool name, quantity, and price:\n");
scanf(" %[^0-9] %d%f", temp.toolName, &temp.inStock,
Price);
fseek(fPtr, temp.partNumber * sizeof(struct hardwareData),
SEEK_SET);
fwrite(&temp, sizeof(struct hardwareData), 1, fPtr);}
else
printf("Cannot update. The record is empty.\n");
}
void insertRecord(FILE *fPtr)
{
struct hardwareData temp;
int part;printf("Enter the partnumber for insertion: ");
scanf("%d", &part);
fseek(fPtr, part * sizeof(struct hardwareData), SEEK_SET);
fread(&temp, sizeof(struct hardwareData), 1, fPtr);
if (!temp.partNumber) {
temp.partNumber = part;
printf("Enter the tool name, quantity, and price:\n");
scanf(" %[^0-9] %d%f", temp.toolName, &temp.inStock,
Price);
fseek(fPtr, temp.partNumber * sizeof(struct hardwareData),
SEEK_SET);
fwrite(&temp, sizeof(struct hardwareData), 1, fPtr);}
else
printf("Cannot insert. The record contains information.\n");
}
void deleteRecord(FILE *fPtr)
{
struct hardwareData blankItem = {0, "", 0, 0.0}, temp;
int part;
printf("Enter the partnumber for deletion: ");
scanf("%d", &part);
fseek(fPtr, part * sizeof(struct hardwareData), SEEK_SET);
fread(&temp, sizeof(struct hardwareData), 1, fPtr);
if (temp.partNumber) {
fseek(fPtr, part * sizeof(struct hardwareData), SEEK_SET);
fwrite(&blankItem, sizeof(struct hardwareData), 1, fPtr);
printf("Record deleted.\n");
}else
printf("Cannot delete. The record is empty.\n");
}
/* Exercise 23.7 Solution */#include <stdio.h>
main()
{
FILE *outPtr;
outPtr = fopen("datasize.dat", "w");
fprintf(outPtr, "%s%16s\n", "Data type", "Size");
fprintf(outPtr, "%s%21d\n", "char", sizeof(char));
fprintf(outPtr, "%s%12d\n", "unsigned char", sizeof(unsigned char));
fprintf(outPtr, "%s%16d\n", "short int", sizeof(short int));fprintf(outPtr, "%s%7d\n", "unsigned short int",
sizeof(unsigned short int)); fprintf(outPtr, "%s%22d\n", "int", sizeof(int));
fprintf(outPtr, "%s%13d\n", "unsigned int", sizeof(unsigned int));
fprintf(outPtr, "%s%17d\n", "long int", sizeof(long int));
fprintf(outPtr, "%s%8d\n", "unsigned long int",
sizeof(unsigned long int));
fprintf(outPtr, "%s%20d\n", "float", sizeof(float));
fprintf(outPtr, "%s%19d\n", "double", sizeof(double));fprintf(outPtr, "%s%14d\n", "long double", sizeof(long double));
fclose(outPtr);
return 0;
}
Data type Size
char 1
unsigned char 1
short int 2
unsigned short int 2
int 2
unsigned int 2
long int 4
unsigned long int 4
float 4
double 10
long double 10
e)if ((tfPtr = fopen("tools.dat", "w")) != NULL)
FILE *cfPtr;
if ((cfPtr = fopen("clients.dat", "w")) == NULL)names the file--"clients.dat"--to be used by the program and establishes a "line of communication" with the file. The file pointer cfPtr is assigned a pointer to the FILE structure for the file opened with fopen.
while (!feof(stdin))uses function feof to determine whether the end-of-file indicator is set for the file to which stdin refers. The end-of-file indicator informs the program that there is no more data to be processed. In the program of Fig.
fprintf(cfPtr, "%d %s %.2f\n", account,writesname,balance);
FILE *cfPtr;indicates that cfPtr is a pointer to a FILE. The line
if ((cfPtr = fopen("clients.dat", "r")) == NULL)attempts to open the file "clients.dat" for reading ("r"), and determines whether the file is opened successfully (i.e., fopen does not return NULL). The statement
fscanf(cfPtr, "%d%s%f", &account, name, &balance);reads a "record" from the file. Function fscanf is equivalent to function scanf except fscanf receives as an argument a file pointer for the file from which the data is read. After the preceding statement is executed the first time, account will have the value 100, name will have the value "Jones", and balance will have the
rewind(cfPtr);
300 White 0.00If the record is rewritten beginning at the same location in the file using the new name, the record would be
300 Worthington 0.00
The new record is larger than the original record. The
characters beyond the second "o" in "Worthington"
would overwrite the beginning of the next sequential
fprintf(fPtr, "%d", number);
fwrite(&number, sizeof(int), 1, fPtr);which always writes 4 bytes (or 2 bytes on a system with 2-byte integers) from variable number to the file represented by fPtr (we will explain the 1 argument shortly). Later, fread can be used to read 4 of those bytes into integer variable number. Although fread and fwrite read and write data such as integers in fixed- size rather than variable-size format, the data they handle is processed in computer "raw data" format (i.e.,
fwrite(&blankClient, sizeof(struct clientData),1, cfPtr);
fseek(cfPtr, (accountNum - 1)positions the file position pointer for the file referenced by cfPtr to the byte location calculated by* sizeof(struct clientData), SEEK_SET);
int fseek(FILE *stream, long int offset, int whence);where offset is the number of bytes from location whence in the file pointed to by stream. The argument whence can have one of three values--SEEK_SET, SEEK_CUR or SEEK_END--indicating the location in the file from which the seek begins. SEEK_SET
fread(&client, sizeof(struct clientData), 1, cfPtr);reads the number of bytes determined by sizeof(struct clientData) from the file referenced by cfPtr and stores the data in the structure client. The bytes are read from the location in the file specified by the file position pointer. Function fread can be used to read several fixed-size array elements by providing a pointer to the
Processing Program
Acct Last Name First Name BalanceOption 2 calls the function updateRecord to update an account. The function will only update a record that already exists, so the function first checks to see if the29 Brown Nancy -24.54
33 Dunn Stacey 314.33
37 Barker Doug 0.00
88 Smith Dave 258.34
96 Stone Sam 34.98
Enter account to update (1 - 100): 37
37 Barker Doug 0.00
Enter charge (+) or payment (-): +87.99
37 Barker Doug 87.99Option 3 calls the function newRecord to add a new account to the file. If the user enters an account number for an existing account, newRecord displays an error message that the record already contains information, and the menu choices are printed again. This function uses the same process to add a new account as does the program in
Enter new account number (1 - 100): 22
Enter lastname, firstname, balance
? Johnston Sarah 247.45